import tkinter as tk
from tkinter import ttk
import os
from tkinter import *
import util
import data as gpdata
from threading import Thread
import gpinfo

# 股票数据获取
def get_news(ids):
    ### 每次麻烦的就是需要在下面更新股票代码
    res_array = gpdata.real_data(ids)
    for idnex, item in enumerate(res_array):
        tags =  ("red_txt", "red_txt", "red_txt", "red_txt", "red_txt")
        if item['up_num'] > 0:
            item['up_num'] = "+"+str(round(item['up_num'], 2)) + "%"
        elif item['up_num'] == 0:
            item['up_num'] = str(round(item['up_num'], 2)) + "%" 
            tags =  ("black_txt", "black_txt", "black_txt", "black_txt", "black_txt")
        else: 
            item['up_num'] = str(round(item['up_num'], 2)) + "%" 
            tags =  ("green_txt", "green_txt", "green_txt", "green_txt", "green_txt")
        
        item_id = find_item(item['id'])
        if item_id == '':
            tree_view.insert('',index=idnex,values=(item['id'], item['name'],item['now_pri'],item['add_num'],item['up_num']), tags=tags)
        else:
            tree_view.item(item_id, values=(item['id'], item['name'],item['now_pri'],item['add_num'],item['up_num']), tags=tags)


# 
def get_ids(arr):
    ids = []
    for id in arr:
        if (len(id) == 0):
            break
        ids.append(id)
    return ids


# 数据刷新的回调
def refreshDate():
	  # 获取数据
    try:
        ids = get_ids(gp_list)
        get_news(ids) 
        treeview_sort_column(tree_view, sort_col, sort_reverse)
    except:
        print("KeyboardInterrupt")
    finally:
        windows.after(1000,refreshDate)

# 当按钮被点击的时候执行click_button()函数
def add_click():
    global stock_file
    input_txt = text_input.get()
    new_id = ''
    if (len(input_txt) > 4):
        save_list(input_txt)

# 保存列表内容
def save_list(new_id):
    global gp_list
    tempArr = []
    
    obj = tree_view.get_children()  # 获取所有对象
    for o in obj:
        values = tree_view.item(o, 'values')
        tempArr.append(values[0])
    
    if ((len(new_id) == 6 or len(new_id) == 5) and new_id.isdigit() or new_id.find('sh') != -1):
        if new_id not in tempArr:
            tempArr.insert(0, new_id)

    gp_list = tempArr
    conf.write("gp","ids", ','.join(tempArr))

#
def find_item(id):
    obj = tree_view.get_children()  # 获取所有对象
    for o in obj:
        values = tree_view.item(o, 'values')
        if (values[0] == id):
            return o
    return ''

#删除
def delete_click():
    tree_view.delete(tree_view.selection())
    save_list('')
 
#窗口透明度
def alpha_change(value):
    windows.wm_attributes('-alpha',value)
    conf.write("windows","alpha", value)

    
def window_destory(event):
    geo = windows.geometry()
    conf.write("windows","geometry", geo)

#窗口自适应
def window_config(event):
    global clistbox_place

    geo = windows.geometry()
    print(geo)
    height_s = geo.find("x")
    height_e= geo.find("+")
    height = int(geo[height_s+1:height_e])
    width = int(geo[0:height_s])

    middle = int(width/2)

    label0.place(x=middle-70 - 35,y=8)
    text_input.place(x=middle-70,y=11,width=140,height=20)
    button_add.place(x=middle+70 + 10,y=5)
    button_dele.place(x=middle+70 + 10 + 40,y=5)


    clomn_with = int((width - 10) / 5)
    tree_view.column('id', width=clomn_with,anchor='center')
    tree_view.column('name', width=clomn_with,anchor='center')
    tree_view.column('price', width=clomn_with,anchor='center')
    tree_view.column('add', width=clomn_with,anchor='center')
    tree_view.column('percent', width=clomn_with,anchor='center')
    tree_view.place(x=5,y=40, width=width - 10, height=height - 52)

    clistbox_place['x'] = middle-70
    clistbox_place['y'] = 30
    clistbox_place['width'] = 140
    clistbox_place['height'] = 100
    clistbox.place(x=clistbox_place['x'], y=clistbox_place['y'], width=clistbox_place['width'],height=clistbox_place['height'])
    clistbox.place_forget()

    scale.place(x=3,y=height - 12,width=width - 6)

#排序
def sort_key(key):
    value = key[0]
    if '%' in value:
        value = value.replace('%', '')
    return float(value)

def treeview_sort_column(tv, col, reverse):#Treeview、列名、排列方式
    global sort_col
    global sort_reverse

    sort_col = col
    sort_reverse = reverse
    l = [(tv.set(k, col), k) for k in tv.get_children('')]
    l.sort(key=sort_key, reverse=reverse)#排序方式
    # rearrange items in sorted positions
    for index, (val, k) in enumerate(l):#根据排序后索引移动
        tv.move(k, '', index)
    tv.heading(col, command=lambda: treeview_sort_column(tv, col, not reverse))#重写标题，使之成为再点倒序的标题

# 获取股票代码
def read_stock_code(file):
    res = []
    try:
        with open(file,'r') as f:
            data = f.read()
            res = data.split('~')
    except:
        pass
    return res


#窗口点击
def window_click(event):
    if hasattr(event.widget, 'widgetName') == False:
        clistbox.place_forget()
        return
    if (event.widget.widgetName == 'entry' or event.widget.widgetName == 'listbox'):
        return
    clistbox.place_forget()

#选择
def list_box_select(event):
    clistbox.place_forget()
    try:
        val = clistbox.get(clistbox.curselection())
        str_code = val.split(' ')[0]
        save_list(str_code)
    except Exception as e:
        pass

#股票检索
def text_input_check(event):
    global stock_codes
    if len(stock_codes) == 0:
        stock_codes = read_stock_code(stock_file)
    global clistbox_place
    input_txt = text_input.get()
    input_txt = input_txt.lower()
    if (input_txt.isdigit() and len(input_txt) < 5 or input_txt == '' or len(input_txt) < 2):
        clistbox.place_forget()
        return
    
    input_listbox_val.set([])
    findArr = []
    for item in stock_codes:
        if (input_txt in item):
            findStr = item.split('`')
            findArr.append(findStr[0]+' '+findStr[1])
            if (len(findArr) > 6):
                break
    if (len(findArr) > 0):
        input_listbox_val.set(findArr)
        clistbox.place(clistbox_place)
    else:
        clistbox.place_forget()

#
def top_level_show(event):
    values = tree_view.item(tree_view.selection()[0], 'values')
    gpinfo.Show(windows, values[0], values[1])


# 显示价格
def show_price():
    # 定义全局变量, 目的是在refreshText 中可以调用这几个变量
    global windows
    global gp_list
    global conf
    global text_input
    global label0
    global button_add
    global scale
    global button_dele
    global tree_view
    global sort_col
    global sort_reverse
    global stock_file
    global clistbox
    global clistbox_place
    global input_listbox_val
    global stock_codes

    sort_col = 'percent'
    sort_reverse = True
    clistbox_place = {}
    input_listbox_val = []

    conf_file = os.getcwd() +'\\config.ini'
    stock_file = os.getcwd() +'\\stock.conf'
    # 创建基础窗口
    windows = tk.Tk()

    conf = util.Conf(conf_file)


    gp_list = []
    ids = conf.read("gp","ids")
    if (len(ids) > 5):
        gp_list = ids.split(",")

    screen_w = windows.winfo_screenwidth()
    screen_h = windows.winfo_screenheight() - 80
    win_w = 450
    win_h = 420
    
    geome = conf.read("windows","geometry")
    if (len(geome) > 0):
        win_info = geome
    else:
        win_info = "{w}x{h}+{left}+{right}".format(w=win_w, h=win_h, left=screen_w-win_w, right=screen_h-win_h)
    windows.geometry(win_info)       ## 规定窗口大小500*500像素
    windows.resizable(True, True)   ## 规定窗口不可缩放
    
    # 定义组件
    label0 = tk.Label(windows,text="代码:")
    text_input = tk.Entry(windows)
    button_add = tk.Button(windows,text='添加',bg='#7CCD7C',command=add_click)
    button_dele = tk.Button(windows,text='删除',bg='#FFFFFF',command=delete_click)
    

    columns = ["id", "name", "price", 'add', 'percent']
    # 使用ttk创建一个树状图
    tree_view = ttk.Treeview(windows,
                                    show="headings",
                                    columns=columns,
                                    height=10,
                                    )
    # 设置列名

    # 给列名设置显示的名字
    tree_view.heading('id', text='代码')
    tree_view.heading('name', text='名称')
    tree_view.heading('price', text='现价')
    tree_view.heading('add', text='涨跌额')
    tree_view.heading('percent', text='涨跌幅')
    for col in columns:#给所有标题加（循环上边的“手工”）
        tree_view.heading(col, command=lambda _col=col: treeview_sort_column(tree_view, _col, False))

    tree_view.tag_configure("red_txt",foreground="red") # 设置标签
    tree_view.tag_configure("black_txt",foreground="black") # 设置标签
    tree_view.tag_configure("green_txt",foreground="green") # 设置标签

    
    input_listbox_val = tk.StringVar()
    clistbox = tk.Listbox(windows, listvariable=input_listbox_val)
    # 设置下拉菜单中的值

    alpha = conf.read("windows","alpha")
    if (len(alpha) == 0):
        alpha = 0.8
    scale=Scale(windows, from_ =0, to=1,resolution =0.1,length =300,label =''
                ,showvalue=False,width=5,orient=tk.HORIZONTAL,command=alpha_change)
    scale.set(value=alpha)
    windows.wm_attributes('-alpha',alpha)
    windows.wm_attributes('-topmost',1)
    text_input.bind("<KeyRelease>", text_input_check)
    text_input.bind("<FocusOut>", text_input_check)
    text_input.bind("<FocusIn>", text_input_check)

    clistbox.bind("<Double-Button-1>", list_box_select)
    tree_view.bind("<Double-1>", top_level_show)


    windows.bind("<ButtonPress-1>",window_click)
    windows.bind("<Destroy>",window_destory)
    windows.bind("<Configure>",window_config)

    #更新股票信息
    t = Thread(target=gpdata.get_stock_codes, args=(stock_file,))
    t.start()

    stock_codes = read_stock_code(stock_file)
   # windows.bind("<Button-1>",MouseDown)  # 按下鼠标左键绑定MouseDown函数
   # windows.bind("<B1-Motion>",MouseMove)  # 鼠标左键按住拖曳事件,3个函数都不要忘记函数写参数
   # windows.bind("<Double-Button-1>",exit)  # 双击鼠标左键，关闭窗体

    windows.after(1000,refreshDate)
    windows.mainloop()

if __name__ == '__main__':
    show_price()
